import 'dart:convert';

import 'package:html/dom.dart';
import 'package:html/parser.dart';
import 'package:json_path/json_path.dart';

import '../rule.dart';
import 'single_rule.dart';
import 'package:flutter_book/util/extensions/string_extensions.dart';

class JsoupParser extends IParser<SingleRule> {
  JsoupParser(SingleRule rule) : super(rule);

  @override
  Future<String> getString(String xml, {Map<String, dynamic>? valueMap}) async {
    var element = parse(xml);
    // print(element);
//"class.sResult@tag.li|class.newShow@tag.li

    var jsoup = rule.ruleContent;
    if (jsoup.startsWith(r'$')) {
      jsoup = jsoup.substring(1);
    }
    if (jsoup.startsWith('class.')) {
      jsoup = jsoup.substring(5);
    }
    if (jsoup.startsWith('tag.')) {
      jsoup = jsoup.substring(4);
    }
    var list = jsoup.split('@');
    var firstQuery = <Element>[];
    var word;
    if (list[0].contains(' ')) {
      word = list[0].replaceAll(' ', r'.');
    } else {
      word = list[0];
    }
    //deal with space
    //col-md-2 col-sm-4 col-xs-4
    // for (var word in queryWords) {
    var position = -1;
    if (word.contains(r'.')) {
      try {
        position = int.parse(word.split(r'.')[1]);
        word = word.split(r'.')[0];
      } catch (e) {
        print(e.toString());
      }
    }

    // if (firstQuery.isEmpty) {
    var temp = element.querySelectorAll(word);
    if (position == -1) {
      firstQuery.addAll(temp);
    } else {
      firstQuery.add(temp[position]);
    }
    // } else {
    //   var temp = <Element>[];
    //   for (var e in firstQuery) {
    //     temp.addAll(e.querySelectorAll(word));
    //   }
    //   if (position == -1) {
    //     firstQuery.addAll(temp);
    //   } else {
    //     firstQuery.add(temp[position]);
    //   }
    // }
    // }

    //deal with tag
    if (list.length > 1) {
      if (firstQuery.isNotEmpty) {
        for (var tag in list.sublist(1)) {
          if (tag == 'text') {
            return firstQuery.map((e) => e.text).first;
          }
          if (tag == 'href') {
            return firstQuery.map((e) => e.attributes['href'].toString()).first;
          }
          var temp = <Element>[];
          for (var e in firstQuery) {
            temp.addAll(e.querySelectorAll(tag));
          }
          firstQuery = temp;
        }
      }
    }

    for (var e in firstQuery) {
      print(e.outerHtml);
    }
    if (firstQuery.isNotEmpty) {
      return (firstQuery.first.outerHtml);
    } else {
      return '';
    }

    var r = rule.ruleContent;
    var attr = '';
    if (r.contains('@')) {
      attr = r.split('@')[1];
      r = r.split('@')[0];
    }
    var item = element.querySelectorAll(r).first;
    if (attr.isEmpty) {
      return item.outerHtml;
    } else {
      return item.attributes[attr]!;
    }
  }

  @override
  Future<List<String>> getStringList(String xml, {Map<String, dynamic>? valueMap}) async {
    var jsoup = rule.ruleContent;

    try {
      if (jsoup.contains("@")) {
        var jsuopArray = jsoup.split("@");
        return analyzeBookList(xml, jsuopArray, 0);
      } else {
        return analyzeBookList(xml, [jsoup], 0);
      }
    } catch (e) {
      "解析报错了".print;
      return [];
    }
  }

  List<String> analyzeBookList(String xml, List<String> jsoupArray, [int index = 0]) {
    if (index == jsoupArray.length) {
      return [xml];
    }

    JsuopKind type = JsuopKind.CLASS;

    var jsoup = jsoupArray[index];

    if (jsoup.startsWith('class.')) {
      type = JsuopKind.CLASS;
      jsoup = jsoup.substring(6);
    } else if (jsoup.startsWith('tag.')) {
      type = JsuopKind.TAG;
      jsoup = jsoup.substring(4);
    } else if (jsoup.startsWith('id.')) {
      type = JsuopKind.ID;
      jsoup = jsoup.substring(3);
    } else if (jsoup.startsWith('.')) {
      type = JsuopKind.CLASS;
      if (jsoup.contains(" ") && index == 0) {
        jsoupArray = jsoup.split(" ");
        jsoup = jsoupArray[0];
      }
      jsoup = jsoup.substring(1);
    } else if (jsoup.startsWith('#')) {
      type = JsuopKind.ID;
      if (jsoup.contains(" ") && index == 0) {
        jsoupArray = jsoup.split(" ");
        jsoup = jsoupArray[0];
      }
      jsoup = jsoup.substring(1);
    } else if (jsoup.startsWith('ul.')) {
      type = JsuopKind.CLASS;
      if (jsoup.contains(" ") && index == 0) {
        jsoupArray = jsoup.split(" ");
        jsoup = jsoupArray[0];
      }
      jsoup = jsoup.substring(3);
    } else if (jsoup.startsWith('ul#')) {
      type = JsuopKind.ID;
      if (jsoup.contains(" ") && index == 0) {
        jsoupArray = jsoup.split(" ");
        jsoup = jsoupArray[0];
      }
      jsoup = jsoup.substring(3);
    } else if (jsoup.startsWith('div.')) {
      type = JsuopKind.CLASS;
      jsoup = jsoup.substring(4);
    } else {
      // "没有找到jsoup的解析方式:$jsoup".print;
      type = JsuopKind.TAG;
    }

    if (jsoup.contains(".")) {
      jsoup = jsoup.split(".")[0];
    } else if (jsoup.contains("!")) {
      jsoup = jsoup.split("!")[0];
    } else if (jsoup.contains(":")) {
      jsoup = jsoup.split(":")[0];
    }

    // "搜索规则:$jsoup,$type".print;

    var element = parse(xml);

    List<String> dataHtmlList = [];

    switch (type) {
      case JsuopKind.CLASS:
        dataHtmlList = List.from(element.getElementsByClassName(jsoup).map((e) => e.outerHtml));
        break;
      case JsuopKind.TAG:
        dataHtmlList = List.from(element.getElementsByTagName(jsoup).map((e) => e.outerHtml));
        break;
      case JsuopKind.ID:
        dataHtmlList = [element.getElementById(jsoup)?.outerHtml ?? ""];
        break;
    }

    if (dataHtmlList.length < 1 && jsoup.contains(" ")) {
      jsoup = jsoupArray[index];
      dataHtmlList = analyzeBookList(xml, jsoup.split(" "), 0);
    }

    var bookList = <String>[];

    dataHtmlList.forEach((element) {
      bookList.addAll(analyzeBookList(element, jsoupArray, index + 1));
    });

    return bookList;
  }
}

enum JsuopKind {
  CLASS,
  TAG,
  ID,
}
